﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Text.RegularExpressions;

using FinalProject.BL;
using FinalProject.UI.Controls;

namespace FinalProject.UI
{
    /// <summary>
    /// Interaction logic for DeliveryPage.xaml
    /// </summary>
    public partial class DeliveryPage : UserControl, IBasePage
    {
        private DataGridTextColumn colItem,
                               colDescrip,
                               colWarehouse,
                               colQuantity,
                               colRemainQuantity,
                               colPrice,
                               colTotalAmount;

        public DeliveryPage()
        {
            this.InitializeComponent();
            this.InitializeEvents();
            this.InitializeColumForGrid();
            this.grvDetail.CanUserAddRows = false;
            this.grvDetail.CanUserDeleteRows = false;
            this.grvDetail.AutoGenerateColumns = false;
            this.cmbJournal.IsEnabled = false;
            this.txtDocNumber.IsReadOnly = true;
        }

        private void InitializeColumForGrid()
        {
            this.grvDetail.ColumnHeaderHeight = 30;
            this.colItem = new DataGridTextColumn()
            {
                Header = "Item Name",
                Binding = new Binding("ItemName"),
                IsReadOnly = true,
                Width = 110
            };
            this.grvDetail.Columns.Add(this.colItem);

            this.colWarehouse = new DataGridTextColumn()
            {
                Header = "Warehouse",
                Binding = new Binding("WarehouseName"),
                IsReadOnly = true,
                Width = 150

            };
            this.grvDetail.Columns.Add(this.colWarehouse);
            this.colQuantity = new DataGridTextColumn()
            {
                Header = "Quantity",
                Binding = new Binding("Quantity"),
                IsReadOnly = false,
                Width = 150

            };
            this.grvDetail.Columns.Add(this.colQuantity);

            this.colRemainQuantity = new DataGridTextColumn()
            {
                Header = "Remain Quantity",
                Binding = new Binding("RemainQuantity"),
                IsReadOnly = true,
                Width = 150
            };
            this.grvDetail.Columns.Add(this.colRemainQuantity);

            this.colPrice = new DataGridTextColumn()
            {
                Header = "Price",
                Binding = new Binding("UnitPrice"),
                IsReadOnly = true,
                Width = 150
            };
            this.grvDetail.Columns.Add(this.colPrice);

            this.colTotalAmount = new DataGridTextColumn()
            {
                Header = "Total",
                Binding = new Binding("TotalAmount"),
                IsReadOnly = true,
                Width = 150
            };
            this.grvDetail.Columns.Add(this.colTotalAmount);

            this.colDescrip = new DataGridTextColumn()
            {
                Header = "Description",
                Binding = new Binding("Description"),
                IsReadOnly = false,
                Width = 500
            };
            this.grvDetail.Columns.Add(this.colDescrip);
        }

        private void LoadDataToOrderBox()
        {
            IDictionary<Guid, long> items = OrderManagementBL.GetAllOrderDocumentItem();
            if (items.IsNullOrEmpty()) return;

            this.cmbOrderNumber.ItemsSource = items;
            this.cmbOrderNumber.DisplayMemberPath = "Value";
            this.cmbOrderNumber.SelectedValuePath = "Key";
        }

        private bool ValidationData()
        {
            bool result = true;
            if (this.cmbJournal.SelectedValue == null)
            {
                FormValidation.DisplayWarning(this.cmbJournal, "Please, select your order");
                result = false;
            }
            else
                FormValidation.RemoveWarning(this.cmbJournal);

            bool allIsZero = true;
            foreach (DeliveryRowEntry item in this.grvDetail.Items)
            {
                if (item.Quantity > 0)
                {
                    allIsZero = false;
                    if (!ItemBL.IsInStock(item.ItemId, item.Quantity))
                    {
                        result = false;
                        Utilities.GetMessageInfo(string.Format("Item {0} is out of stock", item.ItemName));
                        break;
                    }
                }
            }
            if (allIsZero)
            {
                result = false;
                Utilities.GetMessageInfo("Delivery note cannot be made, because it doesn't have quantity");
            }
            return result;
        }

        public void SaveData()
        {
            if (this.ValidationData())
            {
                DAL.Model.DeliveryDocument header = new DAL.Model.DeliveryDocument();
                header.CustomerId = this.lkuCustomer.SelectedId;
                header.DocNumber = Convert.ToInt32(this.txtDocNumber.Text);
                header.DocDate = this.dprCreateDate.SelectedDate;
                header.OrderDocumentId = (Guid)this.cmbOrderNumber.SelectedValue;
                header.DocAddress = this.txtDeliveryAddress.Text;
                header.Desciption = this.txtNote.Text;

                IList<DeliveryRowEntry> lstDetail = new List<DeliveryRowEntry>();
                foreach (DeliveryRowEntry item in this.grvDetail.Items)
                {
                    if (item.Quantity > 0)
                        lstDetail.Add(item);
                }

                bool success = DeliveryManagementBL.InsertOrUpdate(header, lstDetail);
                if (success)
                {
                    Utilities.GetMessageInfo("Your delivery note save success");
                    this.ChangeToNewMode();
                }
            }
        }

        public void CancelModified()
        {
        }

        public void ChangeToNewMode()
        {
            this.txtDocNumber.Text = DeliveryManagementBL.GetLastestNumber().ToString();
            this.dprCreateDate.SelectedDate = null;
            this.cmbOrderNumber.SelectedIndex = -1;
            this.lkuCustomer.SetSelectedValue(null);
            this.txtDeliveryAddress.Text = string.Empty;
            this.txtNote.Text = string.Empty;
            this.grvDetail.ItemsSource = null;
        }

        public void ChangeToNormalMode()
        {
        }

        #region Events
        private void InitializeEvents()
        {
            this.Loaded += DeliveryPage_Loaded;
            this.cmbOrderNumber.SelectionChanged += cmbOrderNumber_SelectionChanged;
        }

        private void cmbOrderNumber_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (this.cmbOrderNumber.SelectedValue == null) return;

            Guid orderId = (Guid)this.cmbOrderNumber.SelectedValue;
            this.LoadData(orderId);
        }

        private void LoadData(Guid orderId)
        {
            FinalProject.DAL.Model.OrderDocument orderDoc = OrderManagementBL.LoadById(orderId);
            if (orderDoc == null) return;

            this.lkuCustomer.SetSelectedValue(orderDoc.Customer);
            this.txtDeliveryAddress.Text = orderDoc.DocAddress;
            this.dprCreateDate.SelectedDate = orderDoc.DeliveryDate;
            this.LoadDatToDetailGrid(DeliveryManagementBL.GetAllRowEntryByOrder(orderId));
        }

        private void LoadDatToDetailGrid(IList<DeliveryRowEntry> docRows)
        {
            if (docRows.IsNullOrEmpty()) return;

            this.grvDetail.ItemsSource = docRows;
        }

        void DeliveryPage_Loaded(object sender, RoutedEventArgs e)
        {
            this.cmbJournal.GetAllItems();
            this.cmbJournal.SelectedValue = BL.DeliveryManagementBL.LoadDeliveryDefaultJournal();

            System.Windows.Style textStyle = new System.Windows.Style(typeof(TextBox));
            System.Windows.EventSetter previewTextInput = new System.Windows.EventSetter(TextBox.PreviewTextInputEvent, new TextCompositionEventHandler(Quantity_TextPreview));
            System.Windows.EventSetter textChangeEvent = new System.Windows.EventSetter(TextBox.TextChangedEvent, new TextChangedEventHandler(Quantity_TextChanged));
            textStyle.Setters.Add(previewTextInput);
            textStyle.Setters.Add(textChangeEvent);
            this.colQuantity.EditingElementStyle = textStyle;

            this.txtDocNumber.Text = DeliveryManagementBL.GetLastestNumber().ToString();

            this.LoadDataToOrderBox();
            this.cmbOrderNumber.Focus();
        }

        private void Quantity_TextChanged(object sender, TextChangedEventArgs e)
        {

            TextBox txtControl = sender as TextBox;
            if (txtControl == null) return;

            if (!string.IsNullOrEmpty(txtControl.Text))
            {
                int quantity = Convert.ToInt32(txtControl.Text);
                DeliveryRowEntry selectedItem = this.grvDetail.CurrentCell.Item as DeliveryRowEntry;
                if (quantity > selectedItem.RemainQuantity)
                {
                    Utilities.GetMessageWarning("Cannot bigger than remaining quantity");
                    txtControl.Text = Convert.ToString(0);
                }

                if (ItemBL.IsInStock(selectedItem.ItemId, quantity))
                {
                    selectedItem.TotalAmount = quantity * selectedItem.UnitPrice;
                    selectedItem.Quantity = quantity;

                    int rowIndex = this.grvDetail.Items.IndexOf(selectedItem);

                    DataGridCell cellTotal = this.grvDetail.GetCell(rowIndex, colTotalAmount.DisplayIndex);
                    cellTotal.Content = selectedItem.TotalAmount;
                }
                else
                {
                    Utilities.GetMessageWarning("Out of stock");
                    txtControl.Text = Convert.ToString(0);
                }
            }
        }

        private void Quantity_TextPreview(object sender, TextCompositionEventArgs e)
        {
            string strInput = e.Text;
            bool valid = Regex.IsMatch(strInput, @"^\d$");
            if (!valid)
            {
                e.Handled = true;
            }
            else
                e.Handled = false;

        }

        #endregion
    }
}